The AddSpriteTrackToMovie function adds the sprites with their initial property values to the key frame sample, as shown in Listing 3-5 . The key frame contains four buttons and two penguins.
If the withBackgroundPicture parameter is true , the function adds a background sprite. The function initializes the background sprite's properties, including setting the layer property to kBackgroundSpriteLayerNum to indicate that the sprite is a background sprite. The function calls SetSpriteData ( Listing 3-6 ), which adds the appropriate property atoms to the spriteData atom container. Then, AddSpriteTrackToMovie calls AddSpriteToSample ( Listing 3-7 ) to add the atoms in the spriteData atom container to the key frame sample atom container.
AddSpriteTrackToMovie adds the other sprites to the key frame sample and then calls AddSpriteSampleToMedia ( Listing 3-8 ) to add the key frame sample to the media.
Listing 5 Creating more key frame sprite media
// add actions to the six sprites
//
// add go to beginning button
myErr = QTCopyAtom(myBeginButton, kParentAtomIsContainer,
&myBeginActionButton);
if (myErr != noErr)
goto bail;
AddSpriteSetImageIndexAction(myBeginActionButton,
kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL,
kGoToBeginningButtonDownIndex, NULL);
AddSpriteSetImageIndexAction(myBeginActionButton,
kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0,
NULL, kGoToBeginningButtonUpIndex, NULL);
AddMovieGoToBeginningAction(myBeginActionButton,
kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton);
AddSpriteSetVisibleAction(myBeginActionButton,
kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL,
true, NULL);
AddSpriteSetVisibleAction(myBeginActionButton,
kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL,
false, NULL);
AddSpriteToSample(mySample, myBeginActionButton,
kGoToBeginningSpriteID);
QTDisposeAtomContainer(myBeginActionButton);
// add go to prev button
myErr = QTCopyAtom(myPrevButton, kParentAtomIsContainer,
&myPrevActionButton);
if (myErr != noErr)
goto bail;
AddSpriteSetImageIndexAction(myPrevActionButton,
kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL,
kGoToPrevButtonDownIndex, NULL);
AddSpriteSetImageIndexAction(myPrevActionButton,
kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0,
NULL, kGoToPrevButtonUpIndex, NULL);
AddMovieStepBackwardAction(myPrevActionButton,
kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton);
AddSpriteSetVisibleAction(myBeginActionButton,
kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL,
true, NULL);
AddSpriteSetVisibleAction(myBeginActionButton,
kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL,
false, NULL);
AddSpriteToSample(mySample, myPrevActionButton, kGoToPrevSpriteID);
QTDisposeAtomContainer(myPrevActionButton);
// add go to next button
myErr = QTCopyAtom(myNextButton, kParentAtomIsContainer,
&myNextActionButton);
if (myErr != noErr)
goto bail;
For each new property value that is passed into it as a parameter, the SetSpriteData function ( Listing 3-6 ) calls QTFindChildByIndex to find the appropriate property atom. If the property atom already exists in the QT atom container, SetSpriteData calls QTSetAtomData to update the property's value. If the property atom does not exist in the container, SetSpriteData calls QTInsertChild to insert a new property atom.
Listing 6 The SetSpriteData function
OSErr SetSpriteData (QTAtomContainer sprite, Point *location,
short *visible, short *layer, short *imageIndex)
{
OSErr err = noErr;
QTAtom propertyAtom;
if (location) {
MatrixRecordmatrix;
// set up the value for the matrix property
SetIdentityMatrix (&matrix);
matrix.matrix[2][0] = ((long)location->h << 16);
matrix.matrix[2][1] = ((long)location->v << 16);
// if no matrix atom is in the container, insert a new one
if ((propertyAtom = QTFindChildByIndex (sprite, 0,
kSpritePropertyMatrix, 1, nil)) == 0)
FailOSErr (QTInsertChild (sprite, 0, kSpritePropertyMatrix,
1, 0, sizeof(MatrixRecord), &matrix, nil))
// otherwise, replace the atom's data else
FailOSErr (QTSetAtomData (sprite, propertyAtom,
sizeof(MatrixRecord), &matrix));
}
// ...
// handle other properties in a similar fashion
// ...
return err;
}
The AddSpriteToSample function ( Listing 3-7 ) checks to see whether a sprite has already been added to a sample. If not, the function calls QTInsertChild to create a new sprite atom in the atom container that represents the sample. Then, AddSpriteToSample calls QTInsertChildren to insert the atoms in the sprite atom container as children of the newly created atom in the sample container.
Listing 7 The AddSpriteToSample function
OSErr AddSpriteToSample (QTAtomContainer theSample,
QTAtomContainer theSprite, short spriteID)
{
OSErr err = noErr;
QTAtom newSpriteAtom;
FailIf (QTFindChildByID (theSample, 0, kSpriteAtomType, spriteID,
nil), paramErr);
FailOSErr (QTInsertChild (theSample, 0, kSpriteAtomType, spriteID,
0, 0, nil, &newSpriteAtom)); // index of zero means append
FailOSErr (QTInsertChildren (theSample, newSpriteAtom, theSprite));
bail:
return err;
}
The AddSpriteSampleToMedia function, shown in Listing 3-8 , calls AddMediaSample to add either a key frame sample or an override sample to the sprite media.
Listing 8 The AddSpriteSampleToMedia function
OSErr AddSpriteSampleToMedia (Media theMedia, QTAtomContainer sample,
TimeValue duration, Boolean isKeyFrame)
{
OSErr err = noErr;
SampleDescriptionHandle sampleDesc = nil;
FailMemErr (sampleDesc = (SampleDescriptionHandle) NewHandleClear(
sizeof(SampleDescription)));
FailOSErr (AddMediaSample (theMedia, (Handle) sample, 0,
GetHandleSize(sample), duration, sampleDesc, 1,
isKeyFrame ? 0 : mediaSampleNotSync, nil));
bail:
if (sampleDesc)
DisposeHandle ((Handle)sampleDesc);
return err;
}
| Previous | Chapter Contents | Chapter Top | Next |